package com.mdd.front.service.category.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mdd.common.constant.GlobalConstant;
import com.mdd.common.core.PageResult;
import com.mdd.common.entity.goods.GoodsCategory;
import com.mdd.common.entity.goods.Goods;
import com.mdd.common.enums.RecommendEnum;
import com.mdd.common.enums.ShowEnum;
import com.mdd.common.mapper.category.GoodsCategoryMapper;
import com.mdd.common.mapper.goods.GoodsMapper;
import com.mdd.common.mapper.unit.GoodsUnitMapper;
import com.mdd.common.utils.TimeUtil;
import com.mdd.common.utils.UrlUtil;
import com.mdd.front.service.category.IGoodsCategoryService;
import com.mdd.front.validate.PageParam;
import com.mdd.front.vo.category.GoodsCategoryListVo;
import com.mdd.front.vo.goods.GoodsListVo;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 服务分类实现类
 */
@Service
public class GoodsCategoryServiceImpl extends ServiceImpl<GoodsCategoryMapper, GoodsCategory> implements IGoodsCategoryService {

    @Resource
    GoodsCategoryMapper goodsCategoryMapper;

    @Resource
    private GoodsMapper goodsMapper;

    @Resource
    private GoodsUnitMapper goodsUnitMapper;

    @Override
    public List<GoodsCategoryListVo> listPid(Long pid) {
        LambdaQueryWrapper<GoodsCategory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (pid == null) {
            lambdaQueryWrapper.eq(GoodsCategory::getPid, GlobalConstant.DEFAULT_GOODS_PID);
        } else {
            lambdaQueryWrapper.eq(GoodsCategory::getId, pid);
        }
        lambdaQueryWrapper.eq(GoodsCategory::getIsDelete, GlobalConstant.NOT_DELETE);
        lambdaQueryWrapper.eq(GoodsCategory::getIsShow,1);
        List<GoodsCategory> list = goodsCategoryMapper.selectList(lambdaQueryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            return Lists.newArrayList();
        }
        List<Long> pidIds = list.stream().map(GoodsCategory::getId).distinct().collect(Collectors.toList());
        Map<Long, List<GoodsCategory>> groupMap = Maps.newHashMap();
        if (CollectionUtils.isNotEmpty(pidIds)) {
            LambdaQueryWrapper<GoodsCategory> sonLambdaQueryWrapper = new LambdaQueryWrapper<>();
            sonLambdaQueryWrapper.in(GoodsCategory::getPid, pidIds);
            sonLambdaQueryWrapper.eq(GoodsCategory::getIsDelete, GlobalConstant.NOT_DELETE);
            sonLambdaQueryWrapper.eq(GoodsCategory::getIsShow, 1);
            List<GoodsCategory> sonList = goodsCategoryMapper.selectList(sonLambdaQueryWrapper);
            groupMap = sonList.stream().collect(Collectors.groupingBy(GoodsCategory::getPid));
        }
        Map<Integer, String> recommendMap = RecommendEnum.getMap();
        Map<Integer, String> showMap = ShowEnum.getMap();
        List<GoodsCategoryListVo> targetList = Lists.newArrayList();
        for (GoodsCategory goodsCategory : list) {
            GoodsCategoryListVo vo = new GoodsCategoryListVo();
            BeanUtils.copyProperties(goodsCategory, vo);
            vo.setIsShowName(showMap.get(vo.getIsShow()));
            vo.setIsRecommendName(recommendMap.get(vo.getIsRecommend()));
            vo.setImage(UrlUtil.toAbsoluteUrl(goodsCategory.getImage()));
            vo.setCreateTime(TimeUtil.timestampToDate(goodsCategory.getCreateTime()));
            vo.setUpdateTime(TimeUtil.timestampToDate(goodsCategory.getUpdateTime()));
            if (groupMap.containsKey(goodsCategory.getId())) {
                List<GoodsCategoryListVo> sonList = Lists.newArrayList();
                List<GoodsCategory> categoryList = groupMap.get(goodsCategory.getId());
                for (GoodsCategory category : categoryList) {
                    GoodsCategoryListVo sonVo = new GoodsCategoryListVo();
                    BeanUtils.copyProperties(category, sonVo);
                    sonVo.setImage(UrlUtil.toAbsoluteUrl(category.getImage()));
                    sonVo.setIsRecommendName(recommendMap.get(sonVo.getIsRecommend()));
                    sonVo.setIsShowName(showMap.get(sonVo.getIsShow()));
                    sonList.add(sonVo);
                }
                vo.setSons(sonList);
            }
            targetList.add(vo);
        }
        return targetList;
    }

    @Override
    public List<GoodsCategoryListVo> listRecommend() {
        LambdaQueryWrapper<GoodsCategory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(GoodsCategory::getPid, GlobalConstant.DEFAULT_GOODS_PID);
        lambdaQueryWrapper.eq(GoodsCategory::getIsDelete, GlobalConstant.NOT_DELETE);
        lambdaQueryWrapper.eq(GoodsCategory::getIsRecommend, RecommendEnum.IS_RECOMMEND.getCode());
        lambdaQueryWrapper.eq(GoodsCategory::getIsShow, 1);
        List<GoodsCategory> list = goodsCategoryMapper.selectList(lambdaQueryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            return Lists.newArrayList();
        }
        List<Long> pidList = list.stream().map(GoodsCategory::getId).distinct().collect(Collectors.toList());
        Map<Long, List<GoodsListVo>> goodsMap = Maps.newHashMap();
        for (Long pid : pidList) {
            LambdaQueryWrapper<GoodsCategory> pidWrapper = new LambdaQueryWrapper<>();
            pidWrapper.eq(GoodsCategory::getId, pid);
            pidWrapper.or().eq(GoodsCategory::getPid, pid);
            pidWrapper.orderByAsc(GoodsCategory::getPid);
            pidWrapper.orderByDesc(GoodsCategory::getSort);
            pidWrapper.orderByAsc(GoodsCategory::getId);
            pidWrapper.last("limit 2");
	        List<GoodsCategory> sonList = super.list(pidWrapper);
            //System.out.println("aaaaaa");
            if (CollectionUtils.isNotEmpty(sonList)) {
                List<Long> sonIds = sonList.stream().map(item -> item.getId()).distinct().collect(Collectors.toList());
                LambdaQueryWrapper<Goods> goodsWrapper = new LambdaQueryWrapper<>();
                goodsWrapper.in(Goods::getCategoryId, sonIds);
                goodsWrapper.eq(Goods::getStatus,1);
                goodsWrapper.eq(Goods::getIsDelete,0);
                goodsWrapper.orderByDesc(Goods::getSort);
                goodsWrapper.last("limit 3");
                List<Goods> goodsList = goodsMapper.selectList(goodsWrapper);
                List<GoodsListVo> goodsListVoList = Lists.newArrayList();
                if (CollectionUtils.isNotEmpty(goodsList)) {
                    List<Long> unitIds = goodsList.stream().map(item -> item.getUnitId()).distinct().collect(Collectors.toList());
                    Map<Long, String> unitMap = goodsUnitMapper.listByIds(unitIds).stream().collect(Collectors.toMap(item -> item.getId(), item -> item.getName()));
                    for (Goods goods : goodsList) {
                        GoodsListVo vo = new GoodsListVo();
                        BeanUtils.copyProperties(goods, vo);
                        vo.setUnit(unitMap.get(goods.getUnitId()));
                        vo.setImage(UrlUtil.toAbsoluteUrl(goods.getImage()));
                        goodsListVoList.add(vo);
                    }
                }
                goodsMap.put(pid, goodsListVoList);
            }
        }
        List<GoodsCategoryListVo> targetList = Lists.newArrayList();
        for (GoodsCategory category : list) {
            GoodsCategoryListVo vo = new GoodsCategoryListVo();
            vo.setCreateTime(TimeUtil.timestampToDate(category.getCreateTime()));
            vo.setUpdateTime(TimeUtil.timestampToDate(category.getUpdateTime()));
            BeanUtils.copyProperties(category, vo);
            vo.setSonGoodsList(goodsMap.get(category.getId()));
            targetList.add(vo);
        }
        return targetList;
    }

    /**
     * 服务分类列表
     *
     * @param pageParam 分页参数
     * @param params    搜索参数
     * @return PageResult<GoodsCategoryListVo>
     */
    @Override
    public PageResult<GoodsCategoryListVo> list(PageParam pageParam, Map<String, String> params) {
        Integer page = pageParam.getPageNo();
        Integer limit = pageParam.getPageSize();

        QueryWrapper<GoodsCategory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_delete", GlobalConstant.NOT_DELETE);
        queryWrapper.eq("is_show", 1);
        queryWrapper.orderByDesc(Arrays.asList("sort", "id"));

        goodsCategoryMapper.setSearch(queryWrapper, params, new String[]{
                "like:name:str",
                "=:pid:long",
                "=:level:int",
                "=:image:str",
                "=:sort:int",
                "=:isShow@is_show:int",
                "=:isRecommend@is_recommend:int",
        });

        IPage<GoodsCategory> iPage = goodsCategoryMapper.selectPage(new Page<>(page, limit), queryWrapper);

        List<GoodsCategoryListVo> list = new LinkedList<>();
        List<Long> pidIds = iPage.getRecords().stream().map(GoodsCategory::getId).distinct().collect(Collectors.toList());
        List<GoodsCategory> pidGoods = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(pidIds)) {
            LambdaQueryWrapper<GoodsCategory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.in(GoodsCategory::getPid, pidIds);
            lambdaQueryWrapper.eq(GoodsCategory::getIsDelete, GlobalConstant.NOT_DELETE);
            lambdaQueryWrapper.eq(GoodsCategory::getIsShow, 1);
            pidGoods = goodsCategoryMapper.selectList(lambdaQueryWrapper);
        }
        Map<Long, List<GoodsCategory>> pidGroupGoodsMap = Maps.newHashMap();
        if (CollectionUtils.isNotEmpty(pidGoods)) {
            pidGroupGoodsMap = pidGoods.stream().collect(Collectors.groupingBy(GoodsCategory::getPid));
        }
        Map<Integer, String> recommendMap = RecommendEnum.getMap();
        Map<Integer, String> showMap = ShowEnum.getMap();
        for (GoodsCategory item : iPage.getRecords()) {
            GoodsCategoryListVo vo = new GoodsCategoryListVo();
            BeanUtils.copyProperties(item, vo);
            vo.setImage(UrlUtil.toAbsoluteUrl(item.getImage()));
            vo.setCreateTime(TimeUtil.timestampToDate(item.getCreateTime()));
            vo.setUpdateTime(TimeUtil.timestampToDate(item.getUpdateTime()));
            vo.setIsRecommendName(recommendMap.get(vo.getIsRecommend()));
            vo.setIsShowName(showMap.get(vo.getIsShow()));
            if (pidGroupGoodsMap.containsKey(item.getId())) {
                List<GoodsCategory> categoryList = pidGroupGoodsMap.get(item.getId());
                List<GoodsCategoryListVo> sons = Lists.newArrayList();
                for (GoodsCategory category : categoryList) {
                    GoodsCategoryListVo son = new GoodsCategoryListVo();
                    BeanUtils.copyProperties(category, son);
                    son.setImage(UrlUtil.toAbsoluteUrl(category.getImage()));
                    son.setIsRecommendName(recommendMap.get(son.getIsRecommend()));
                    son.setIsShowName(showMap.get(son.getIsShow()));
                    son.setCreateTime(TimeUtil.timestampToDate(category.getCreateTime()));
                    son.setUpdateTime(TimeUtil.timestampToDate(category.getUpdateTime()));
                    sons.add(son);
                }
                vo.setSons(sons);
            }
            list.add(vo);
        }
        return PageResult.iPageHandle(iPage.getTotal(), iPage.getCurrent(), iPage.getSize(), list);
    }

}
